/*
 * Meow meow player v0.3.0 - a music player built with HTML5 audio API =>_<=
 * Author:Wayou
 * lisenced under the MIT license
 * for more information you can
 * visit the project page on github :https://github.com/Wayou/MeowmeowPlayer/
 * see the live demo :http://wayou.github.io/MeowmeowPlayer/
 * or contact me: liuwayong@gmail.com
 */
'use strict'

var MmPlayer = function () {
  this.audioContext = null
  this.source = null
  this.playlist = []
  this.currentOrderNum = 0 // orderNum starts from 0
  this.status = 0 // 1 for stopped and 1 for playing
  this.canvas = null
  this.animationId = null
  this.audioContext = null
  this.forceStop = false
  this.processing = false
  this.type = 'once'// once 只播放一次，keepAlive 一直播放
}
MmPlayer.prototype = {
  ini: function () {
    this._prepareAPI()
  },
  _prepareAPI: function () {
    // fix browser vender for AudioContext and requestAnimationFrame
    window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext
    window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame
    window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame
    try {
      this.audioContext = new AudioContext()
    } catch (e) {
    }
  },
  _decodeFile: function (arraybuffer, type) {
    const that = this
      var audioContext = this.audioContext
    if (audioContext === null) {
      return
    }
    this._disableControl()
    audioContext.decodeAudioData(arraybuffer, function (buffer) {
      that.currentBuffer = buffer
      that._drawSpectrum(audioContext, buffer, type)
    }, function (e) {
      that.processing = false
    })
  },
  _drawSpectrum: function (audioCtx, buffer, type) {
    const that = this
      var source = audioCtx.createBufferSource()
      var analyser = audioCtx.createAnalyser()
      var canvas = document.getElementById('canvas')
      // mirror = this.mirror,
      var canvasCtx = canvas.getContext('2d')
      // mirrorCtx = mirror.getContext('2d'),
      var cwidth = canvas.width
      var cheight = canvas.height - 2
      var meterWidth = 10 // width of the meters in the spectrum
      var capHeight = 2
      var capStyle = '#fff'
      var meterNum = 800 / (10 + 2) // count of the meters
      var capYPositionArray = [] /// /store the vertical position of hte caps for the preivous frame
      var gradient = canvasCtx.createLinearGradient(0, 0, 0, 300)
    // gradient.addColorStop(1, '#0f0');
    gradient.addColorStop(1, '#F3F93B')
    source.buffer = buffer
    source.connect(analyser)
    analyser.connect(audioCtx.destination)
    if (this.source !== null) {
      this.forceStop = true
      this.source.stop(0)
      this.status = 0
    }
    cancelAnimationFrame(this.animationId) // stop the previous animation
    if (type !== 'keepAlive') {
      source.onended = function () {
        window.eventBus.$emit('isStop', 'isStop')
      }
    } else {
      source.onended = function () {
        // that._audioEnd();
        if (that.type === 'keepAlive') {
          window.eventBus.$emit('stop', 'stop')
        }
      }
    }
    source.start(0)
    this.processing = false
    this.source = source
    this.status = 1
    var drawFrame = function () {
      var array = new Uint8Array(analyser.frequencyBinCount)
      analyser.getByteFrequencyData(array)
      // draw the visualizer stuff on the canvas
      var step = Math.round(array.length / meterNum) // sample limited data from the total array
      canvasCtx.clearRect(0, 0, cwidth, cheight)
      for (var i = 0; i < meterNum; i++) {
        var value = array[i * step]
        if (capYPositionArray.length < Math.round(meterNum)) {
          capYPositionArray.push(value)
        }
        canvasCtx.fillStyle = capStyle
        // draw the cap, with transition effect
        if (value < capYPositionArray[i]) {
          canvasCtx.fillRect(i * 12, cheight - (--capYPositionArray[i]), meterWidth, capHeight)
        } else {
          canvasCtx.fillRect(i * 12, cheight - value, meterWidth, capHeight)
          capYPositionArray[i] = value
        }
        ;
        canvasCtx.fillStyle = gradient // set the filllStyle to gradient for a better look
        canvasCtx.fillRect(i * 12 /* meterWidth+gap */, cheight - value + capHeight, meterWidth, cheight) // the meter
      }
      that.animationId = requestAnimationFrame(drawFrame)
    }
    that.animationId = requestAnimationFrame(drawFrame)
  },
  // 定义加载音频文件的函数
  _loadSound: function (url, type) {
    const that = this
    var request = new XMLHttpRequest() // 建立一个请求
    var blob = null
    request.open('GET', url, true) // 配置好请求类型，文件路径等
    request.responseType = 'blob' // 配置数据返回类型
    // 一旦获取完成，对音频进行进一步操作，比如解码
    request.onload = function () {
      if (request.status === 200) {
        if (this.audioContext === null) {
          return
        }
        blob = request.response
        const wavFile = new File([blob], 'test.wav', { type: 'audio/x-wav' })
        if (type) {
          that._readFile(wavFile, type)
        } else {
          that._readFile(wavFile, 'once')
        }
      }
    }
    request.send()
  },
  _readFile: function (myfile, type) { // read file as arraybuffer
    const that = this
    that.type = type
    var file = myfile; var reader = new FileReader()
    reader.onload = function (e) {
      var arraybuffer = e.target.result
      that._decodeFile(arraybuffer, type)
    }
    reader.onerror = function (e) {
      that.processing = false
    }
    reader.readAsArrayBuffer(file)
  },
  _disableControl: function () {
    var overlay = document.createElement('div')
      var loader = document.createElement('div')
      var i = 0
    overlay.className = 'overlay'
    loader.className = 'loader'
    while (i < 5) {
      var circle = document.createElement('div')
      circle.className = 'circle'
      loader.appendChild(circle)
      i++
    }
    overlay.appendChild(loader)
  },
  stop: function () {
    this.forceStop = true
    this.source.stop(0)
    this.status = 0
  },
  _audioEnd: function () {
    // this.audioContext.currentTime=0;
    if (this.forceStop) {
      this.forceStop = false
      return
    }
    this.source = null
    if (this.currentOrderNum === this.playlist.length - 1) {
      this.currentOrderNum = 0
    } else {
      this.currentOrderNum += 1
    }
  },
  addClass: function (el, cls) {
    el.className += ' ' + cls
  },
  removeClass: function (el, cls) {
    var elClass = ' ' + el.className + ' '
    while (elClass.indexOf(' ' + cls + ' ') !== -1) elClass = elClass.replace(' ' + cls + ' ', '')
    el.className = elClass
  }
}

var player = new MmPlayer()
// 导出语句
module.exports.player = player
